<template>
  <div
    v-show="ready"
    class="haloe-carousel-item"
    :class="{
      'is-active': active,
      'haloe-carousel-item-card': isCardType,
      'is-in-stage': inStage,
      'is-hover': hover,
      'is-animating': animating
    }"
    @click="handleItemClick"
    :style="itemStyle">
    <div
      v-if="isCardType"
      v-show="!active"
      class="haloe-carousel-mask">
    </div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'CarouselItem',
}
</script>

<script setup>
import {computed,ref,unref,inject,reactive, getCurrentInstance,onMounted,onUnmounted } from 'vue';
// import random from '../../utils/random_str';
// const prefixCls = 'haloe-carousel-item';
const CARD_SCALE = 0.83;
const carouselContext = inject('carouselContextKey')

// computed
const { isCardType, isVertical } = carouselContext

const props=defineProps({
  name: String,
  label: {
    type: [String, Number],
    default: ''
  }
})

let hover= ref(false)
let translate=ref(0)
let scale=ref(1)
let active=ref(false)
let ready=ref(false)
let inStage=ref(false)
let animating=ref(false)

const itemStyle = computed(() => {
  const translateType = `translate${unref(isVertical) ? 'Y' : 'X'}`
  const _translate = `${translateType}(${unref(translate)}px)`
  const _scale = `scale(${unref(scale)})`
  const transform = [_translate, _scale].join(' ')

  return {
    transform,
  }
})

const processIndex=(index, activeIndex, length)=> {
  if (activeIndex === 0 && index === length - 1) {
    return -1;
  } else if (activeIndex === length - 1 && index === 0) {
    return length;
  } else if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
    return length + 1;
  } else if (index > activeIndex + 1 && index - activeIndex >= length / 2) {
    return -2;
  }
  return index;
}

const calcCardTranslate=(index, activeIndex)=> {
  // const parentWidth = this.$parent.$el.offsetWidth;
  const parentWidth = carouselContext.root.value?.offsetWidth || 0
  if (inStage.value) {
    return parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1) / 4;
  } else if (index < activeIndex) {
    return -(1 + CARD_SCALE) * parentWidth / 4;
  } else {
    return (3 + CARD_SCALE) * parentWidth / 4;
  }
}

const calcTranslate=(
  index,
  activeIndex,
  isVertical)=> {
  const rootEl = carouselContext.root.value
  if (!rootEl) return 0

  const distance =
      (isVertical ? rootEl.offsetHeight : rootEl.offsetWidth) || 0
  return distance * (index - activeIndex)
}

const translateItem = (index,activeIndex,oldIndex) => {
  const _isCardType = unref(isCardType)
  const carouselItemLength = carouselContext.items.value.length ?? Number.NaN

  const isActive = index === activeIndex
  if (!_isCardType && oldIndex !== undefined) {
    animating.value = isActive || index === oldIndex
  }

  if (!isActive && carouselItemLength > 2 && carouselContext.loop) {
    index = processIndex(index, activeIndex, carouselItemLength)
  }

  const _isVertical = unref(isVertical)
  active.value = isActive

  if (_isCardType) {
    if (_isVertical) {
      console.warn(
        'Carousel',
        'vertical direction is not supported for card mode'
      )
    }
    inStage.value = Math.round(Math.abs(index - activeIndex)) <= 1
    translate.value = calcCardTranslate(index, activeIndex)
    scale.value = unref(active) ? 1 : CARD_SCALE
  } else {
    translate.value = calcTranslate(index, activeIndex, _isVertical)
  }

  ready.value = true
}
const instance=getCurrentInstance()

function handleItemClick() {
  if (carouselContext && unref(isCardType)) {
    const index = carouselContext.items.value.findIndex(
      ({ uid }) => uid === instance.uid
    )
    carouselContext.setActiveItem(index)
  }
}

onMounted(()=>{
  carouselContext.addItem({
    props,
    states: reactive({
      hover,
      translate,
      scale,
      active,
      ready,
      inStage,
      animating,
    }),
    uid: instance.uid,
    translateItem,
  })
})

onUnmounted(() => {
  carouselContext.removeItem(instance.uid)
})
</script>